﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using System.Net;
using System.IO;
using System.Collections;
using System.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;
namespace G1
{
   // List<string> 
    public partial class Form1 : Form
    {
        
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            Cursor = Cursors.WaitCursor;
            Crawer crawer = new Crawer();
            
            string starturl = urlin.Text;
            //string starturl = "http://www.cnblogs.com/dstang2000";
            crawer.urls.Add(starturl, false);

            //new Thread(crawer.Crawl).Start();

            while (crawer.count < 10)
            {
                crawer.Crawl();
                if (crawer.wrong==1)
                {
                    this.listBox2.Items.Add(crawer.str);
                }
                else
                {
                    this.listBox1.Items.Add(crawer.str);
                }
                
            }
            if (crawer.wrong == 1&& crawer.str=="")
            {
                this.listBox2.Items.Remove(crawer.str);
            }
            if(crawer.wrong == 0&& crawer.str == "")
            {
                this.listBox1.Items.Remove(crawer.str);
            }
            // List<string> str= crawer.Crawl();
            //foreach(string s in str)
            //{
            //    this.listBox1.Items.Add(s);
            //}
            Cursor = Cursors.Default;
        }

        private void label1_Click(object sender, EventArgs e)
        {

        }
    }

    public class Crawer
    {
        public Hashtable urls = new Hashtable();
        public  int count = 0;
        public string str = "";
        public int wrong = 0;
        public void Crawl()
        {
            Debug.WriteLine("start");
            
            
                Debug.WriteLine(count.ToString());
                string current = null;
                foreach (string url in urls.Keys)
                {
                    if ((bool)urls[url]) continue;
                    current = url;
                }
                if (current == null || count > 10)
                {
                    count = 11;
                    str = "";
                    return;
                }
                Debug.WriteLine("new+" + current);
                string html = Download(current);
                urls[current] = true;
                str = current;
            Debug.WriteLine("this");
                //str.Add(current);
                count++;
            if (wrong == 0) { Prase(html, current); }
            return;

        }


        public string Download(string url)
        {
            try
            {
                wrong = 0;
                WebClient webClient = new WebClient();
                webClient.Encoding = Encoding.UTF8;
                string html = webClient.DownloadString(url);
                if (count < 1)
                {
                    string filename = "myhtml" + count.ToString();
                    File.WriteAllText(filename, html, Encoding.UTF8);
                }
                
                return html;
            }
            catch (Exception ex)
            {
                Debug.WriteLine("wrong");
                wrong = 1;
                return "";
            }
        }

        public string toAbslute(string url, string furl)
        {
            Uri baseuri = new Uri(furl);
            Uri absolute = new Uri(baseuri, url);
            return absolute.ToString();
        }
        public void Prase(string html, string baseurl)
        {
            StreamReader sr = null;
            string text = "";
            try
            {
                sr = new StreamReader("myhtml" + (count - 1).ToString());
                text = sr.ReadLine();
                Debug.WriteLine(text);

            }
            catch
            {
                Debug.WriteLine("read wrong");
            }
            finally
            {
                if (sr != null)
                    sr.Close();
            }
            if (!text.ToLower().Contains("html"))
            {
                Debug.WriteLine("return");
                return;
            }
            string strref = @"(href|HREF)[]*=[]*[""'][^""'#>]+[""']";
            MatchCollection matches = new Regex(strref).Matches(html);
            foreach (Match match in matches)
            {
                strref = match.Value.Substring(match.Value.IndexOf('=') + 1).Trim('"', '#', '>');
                strref = toAbslute(strref, baseurl);
                if (strref.Length == 0) continue;
                if (urls[strref] == null) urls[strref] = false;
            }
        }
    }
}
